home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / NUMBERS.SWG / 0063_Keyboard Latency as a Random Number.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  6KB  |  158 lines

  1. {
  2. > Bruce Schneier suggests keyboard latency as a good source of randomness.
  3. > I suspect you'd find the delays far more regular than you'd guess, but
  4. > it's worth looking at.  Show us an implementation!
  5.  
  6. Thanks, DJ.  (And I was hoping a simple appeal to a recognized authority
  7. would suffice!  I guess I should have known better.)  But fair enough -
  8. here's an admittedly crude implementation:
  9. }
  10.  
  11. program TestKey;
  12.  
  13. { Test keyboard latency as a potential source of random numbers. }
  14. { NOTE - NO ERROR CHECKING!                                      }
  15.  
  16. uses
  17.   Dos, Crt;
  18.  
  19. const
  20.   FileName = 'RANDOM.TST';
  21.  
  22. var
  23.   PrevTime : Word;
  24.   RandByte : Byte;
  25.   Regs     : Registers;
  26.   Bit      : Word;
  27.   RandFile : file of Byte;
  28.   Ch       : Char;
  29.  
  30. begin
  31.   { open the file }
  32.   Assign( RandFile, FileName );
  33.   Rewrite( RandFile );
  34.  
  35.   { get DOS time and save low word }
  36.   Regs.AH := 0;
  37.   Intr( $1A, Regs );
  38.   PrevTime := Regs.DX;
  39.  
  40.   Bit := 0;
  41.   RandByte := 0;
  42.   WriteLn( 'Start typing now.  Press <ESC> to quit.' );
  43.  
  44.   repeat
  45.     { get a keystroke }
  46.     repeat until KeyPressed;
  47.     Ch := ReadKey;
  48.  
  49.     { if the Escape key }
  50.     if Ch = #27 then
  51.       Break;
  52.  
  53.     { get DOS time }
  54.     Regs.AH := 0;
  55.     Intr( $1A, Regs );
  56.  
  57.     { calculate the time difference, isolate the low-order bit, and }
  58.     { use it to build the hopefully-random byte in progress.        }
  59.     RandByte := RandByte + ( ( Lo( Regs.DX - PrevTime ) and 1 ) shl Bit );
  60.     PrevTime := Regs.DX;
  61.     Inc( Bit );
  62.  
  63.     { If we have a full byte, write it to the file and start over }
  64.     if ( Bit > 7 ) then begin
  65.       Write( RandFile, RandByte );
  66.       RandByte := 0
  67.       Bit := 0;
  68.     end;
  69.  
  70.     { Ignore special keys, display the rest }
  71.     if Ch = #0 then
  72.       Ch := ReadKey
  73.     else
  74.       Write( Ch );
  75.     if Ch = #13 then
  76.       Write( #10 )
  77.  
  78.   until False;
  79.   Close( RandFile )
  80. end.
  81.  
  82. {
  83. I ran this thing and typed in the first page of a DOC file.  This is what I
  84. got:
  85.  
  86.   24  98  AD  94  E2  C8  00  58  20  83  09  F1  5D  F5  76  59
  87.   31  A9  86  DC  32  6D  96  17  65  C4  75  31  A3  18  F5  97
  88.   87  0A  69  B4  B6  E7  0A  C1  F8  09  BE  B0  7B  C5  4A  BA
  89.   69  42  8C  D4  E4  71  12  DF  5E  19  5C  A0  0D  79  D7  F1
  90.   66  BC  40  36  E9  8D  DB  B5  37  A9  7A  0C  02  90  05  04
  91.   EA  53  38  CA  94  18  92  8A  46  A6  F1  56  D0  E7  38  97
  92.   25  2D  C3  C8  7E  79  DE  02  58  FC  36  7E  BC  3C  F9  6D
  93.   E6  2E  C0  28  06  AD  C1  4B  55  CD  C4  98  DD  08  DD  4E
  94.   11  56  76  83  BC  7A  AF  05  F6  AC  C3  40  28  D5  2B  8E
  95.   C1  93  B5  F9  54  E2  00  3D  5A  5D  37  36  C3  5F  37  3A
  96.   AB  60  36  72  27  26  21  86  2F  B4  6B  D9  70  94  DE  00
  97.   C8  23  34  5F  83  C9  FB  AF  F8  F5  CE  21  B3  40  FA  ED
  98.   21  4B  65  00  D9  A0  6E  43  E4  FF  66  1B  BC  17  80  29
  99.   FD  6F  10  4B  D7  D3  ED  5C  C9  18  0E  24  89  1F  03  BC
  100.   B3  0B  CB  E5  1E  16  B8  DA  99  EC  93  84  7E  8A  FE  61
  101.   9D  B7  2E  30  11  7F  0A  C6  83  C2  C1  97  3B  08  61  8D
  102.   7B  5E  7E  69  99  F8  F3  36  BA  31  6E  41  60  8C  DC  B7
  103.   48  FB  44  A2  78  D5  AF  88  D9  10  50  E7  C7  BE  68  41
  104.   C2  E8  D8  1B
  105.  
  106. The distribution of bytes looks like this:
  107.  
  108.          0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  109.      +-----------------------------------------------------------------
  110.  0   |   4   0   2   1   1   2   1   0   2   2   3   1   1   1   1   0
  111.  1   |   2   2   1   0   0   0   1   2   3   1   0   2   0   0   1   1
  112.  2   |   1   3   0   1   2   1   1   1   2   1   0   1   0   1   2   1
  113.  3   |   1   3   1   0   1   0   5   3   2   0   1   1   1   1   0   0
  114.  4   |   3   2   1   1   1   0   1   0   1   0   1   3   0   0   1   0
  115.  5   |   1   0   0   1   1   1   2   0   2   1   1   0   2   2   2   2
  116.  6   |   2   2   0   0   0   2   2   0   1   3   0   1   0   2   2   1
  117.  7   |   1   1   1   0   0   1   2   0   1   2   2   2   0   0   4   1
  118.  8   |   1   0   0   4   1   0   2   1   1   1   2   0   2   2   1   0
  119.  9   |   1   0   1   2   3   0   1   3   2   2   0   0   0   1   0   0
  120.  A   |   2   0   1   1   0   0   1   0   0   2   0   1   1   2   0   3
  121.  B   |   1   0   0   2   2   2   1   2   1   0   2   0   5   0   2   0
  122.  C   |   1   4   2   3   2   1   1   1   3   2   1   1   0   1   1   0
  123.  D   |   1   0   0   1   1   2   0   2   1   3   1   1   2   2   2   1
  124.  E   |   0   0   2   0   2   1   1   3   1   1   1   0   1   2   0   0
  125.  F   |   0   3   0   1   0   3   1   0   3   2   1   2   1   1   1   1
  126.  
  127.  
  128. Question - is it random?  Well, it's far too small a sample to be sure, and I
  129. wasn't about to retype "War and Peace" to get a bigger sample.  It passes
  130. one test of randomness - non-compressability.  LHA won't compress it, anyway.
  131. (A text file of similar size compressed to 64%.)  I don't consider this
  132. definite proof of randomness, although it looks hopeful.
  133.  
  134. Question - is it unpredictable?  Given the above source code and the list of
  135. bytes generated, I don't think I could predict what the next byte would be.
  136.  
  137. Question - can it be reliably reproduced?  Not at my level of typing ability,
  138. unless I cheat and just hold down a key.  Even then, there are minor
  139. variations between bytes.
  140.  
  141. Problem - the timer is too coarse.  It uses the BIOS time-of-day count, which
  142. ticks over about 18.2 times per second.  For a 30-wpm (3 character-per-second)
  143. typist like me, it _seems_ to produce acceptable results.  For a professional
  144. typist, churning out 110 wpm (11 characters per second), it probably won't.
  145. Something using the 8253 timer (a modification of the Abrash "Zen Timer", for
  146. example) would probably be adequate for even the fastest typist, but that's a
  147. bit too exotic for me to attempt.
  148.  
  149. Problem - it takes a lot of typing to generate a decent pad.  By my
  150. calculations, a 110-wpm typist would have to type for 20 minutes to create a
  151. pad big enough to encrypt one double-spaced typewritten page.  Possible
  152. solution - rewrite the thing as a TSR, so that a typist can do useful work
  153. while generating random (?) numbers in the background.  Then, turn the whole
  154. typing pool loose on the problem.
  155.  
  156. Does anyone have a better timer routine and a faster typist?
  157. }
  158.